<template>
  <div class="anchor">
        <div v-for="(item,index) in list" :key="index"  @click="handleClick(item.label)"
        :class="[item.ismain?'anchor-main-node':'anchor-sub-node',{'anchor-node-active':currentSection===item.label}]">
      {{item.label}}
      <div :class="item.tip?'highlight-tag':''"></div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, defineProps, computed, defineEmits, onMounted } from 'vue'
import { useDebounceFn } from '@vueuse/core'
 type anchorList ={
  label: string,
  index: string,
isMain:boolean
}
let props = defineProps({
  pageBlock: {
    type: HTMLElement,
    require: true,
      define:()=>{}
  }
})
let currentSection=ref(null)

//获取list
function getSectionsData(pageBlock) {
  let mainIndex = 0
  let subIndex = 0
  //获取dom并转化为数组
  const sections = Array.from(pageBlock.querySelectorAll('[data-section]'))
  // 循环数组
  return sections.map((item:HTMLElement, index) => {
    let ismain = false
    if ('ismain' in item.dataset) {
      ismain = true
      mainIndex++
      // 遇到新的主节点，重置subIndex
      subIndex = 0
    } else {
      subIndex++
    }
    //返回一个list数组，每项包含tip提示，是否为主标题，index（主标题和副标题区分）label文字，offset距离
    return {
      tip: 'tip' in item.dataset,
      ismain,
      index: ismain ? mainIndex : `${mainIndex}.${subIndex}`,
      label: item.dataset.section,
      top: item.offsetTop
    }
  })
}

let list = ref(null)
function handleClick(label) {
  // 设置当前锚点对应章节
  // this.currentSection = label
  // 查找到到该章节的dom
  const section = props.pageBlock.querySelector(`[data-section=${label}]`)
  // 平滑滚动至该章节
  section.scrollIntoView({
      behavior: 'smooth',
      block: 'start'
  })
}
function handleScroll(e) {
  e.stopPropagation()
  currentSection.value = getCurrentSection()
}
function getCurrentSection() {
  //传入dom根节点距离顶部距离
    const currentScrollTop = props.pageBlock.scrollTop
  const sections = list.value
  const length = sections.length
  //循环得到的list
  let currentSection
  // 依次和各节点原先的offsetTop进行比较
  for (let i = 0; i < length; i++) {
    // 如果scrollTop正好和某节点的offsetTop相等
    // 或者scrollTop介于当前判断的节点和下一个节点之间
    // 由于需要下一个节点，所以当前节点不能是最后一个节点
    if (currentScrollTop === sections[i].top ||
      (i < length - 1 &&
        currentScrollTop > sections[i].top &&
        currentScrollTop < sections[i + 1].top)) {
      currentSection = sections[i].label
      break
    } else if (i === length - 1) {//判断最后一个
      // 如果判断到一个节点，只要 scrollTop大于节点的offsetTop即可
      if (currentScrollTop > sections[i].top) {
        currentSection = sections[i].label
        break
      }
    }
  }
  // 返回当前元素
  return currentSection
}
function reRender() {
  //获取list
  list.value = getSectionsData(props.pageBlock)
  //找到当前顶部元素
  currentSection.value = getCurrentSection()
}
onMounted(() => {
  //获取list
  list.value = getSectionsData(props.pageBlock)
  //设置滚动监听，把当前元素赋值给current
  let debounces =useDebounceFn(handleScroll)
  props.pageBlock.addEventListener('scroll', debounces)

  // 
})
//导出rerender
defineExpose({
  reRender,
})
</script>
<style lang="scss" scoped>

.anchor-main-node {
  position: relative;
  margin: 8px 0;
  font-size: 14px;
  font-weight: bold;
  color: #555;
  cursor: pointer;
  &::before {
    // content: attr(label);
    margin-left: 6px;
    margin-right: 6px;
  }
}
.anchor-sub-node {
  position: relative;
  margin: 8px 0;
  padding-left: 22px;
  font-size: 14px;
  color: #666;
  cursor: pointer;
  &::before {
    // content: attr(label);
    margin-right: 4px;
  }
}
.anchor-node-active {
    color: #38f;
}
.highlight-tag {
  display: inline-block;
  text-align: center;
  margin-left: 8px;
  width: 16px;
  height: 16px;
  border-radius: 16px;
  background: crimson;
  color: #efefef;
}
</style>